package com.ybc.completableFuture;

import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;

//自己手写的 CompletableFuture 就写死了 get给删了
//在future的基础之上 多了 thenAccept 方法 可以接受一个 Consumer

public class MyCompletableFuture implements Runnable{


    //回调的方法  由注册监听方法顺便执行（可改为执行器） 或run方法结束之后执行
    private AtomicReference<Consumer> thenConsumer = new AtomicReference<>();


    //主要的任务
    private Callable callable;


    private volatile Object result;

    //0 未完成 1 完成
    private volatile int state;

    public MyCompletableFuture(Callable callable) {
        this.callable = callable;
    }


    //运行完唤醒其他的即可  若他先 则能唤醒  若他后 则他不会阻塞
    public void run() {
        if(state == 1){
            return;
        }
        try {
            result = callable.call();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        state = 1;
        // 这之后 state 必为1  可由then 执行
        Consumer consumer = thenConsumer.getAndSet(null);
        if (consumer != null) {
            consumer.accept(result);
        }
    }

    //回调机制 完成后触发 简单实现 利用cas 实现线程安全
    public  void thenAccept(Consumer consumer){
        //这之后 必有consumer 可由run执行
        if (!thenConsumer.compareAndSet(null, consumer)) {
            throw new IllegalStateException("Only one consumer allowed");
        }

        //如果任务已经完成 则直接调用
        if (state == 1) {
            Consumer c = thenConsumer.getAndSet(null);
            if (c != null) {
                c.accept(result);
            }
        }
    }

}
